//引入cesium基础库
import "mars3d-cesium/Build/Cesium/Widgets/widgets.css";
import * as Cesium from "mars3d-cesium";

//导入mars3d主库
import "mars3d/dist/mars3d.css";
import * as mars3d from "mars3d";

import {
  bindLayerPopupTemplate,
  mapPopupDomEevent,
  computeIcon
} from './utils'

// mars3d.Map三维地图对象
export let map

// 事件对象，用于抛出事件给面板
export const eventTarget = new mars3d.BaseClass()

/**
 * 初始化地图业务，生命周期钩子函数（必须）
 * 框架在地图初始化完成后自动调用该函数
 * @param {mars3d.Map} mapInstance 地图对象
 * @returns {void} 无
 */
export function onMounted(mapInstance) {
  map = mapInstance // 记录map
}

/**
 * 释放当前地图业务的生命周期函数
 * @returns {void} 无
 */
export function onUnmounted(mapInstance) {
  mapInstance?.graphicLayer.clear()
  map = null
  mapInstance = null
}

// 三维地图基本地图配置
export const mapOptions = {
  // 场景:是所有3D图形对象的容器（HTML canvas）
  scene: {
    //默认视角参数
    center: {
      lat: 38.695172,
      lng: 110.169988,
      alt: 2255,
      heading: 341,
      pitch: -90
    },
    shadows: true, //是否启用日照阴影
    removeDblClick: true, //是否移除Cesium默认的双击事件

    //以下是Cesium.Scene对象相关参数
    showSun: true, //是否显示太阳
    showMoon: true, //是否显示月亮
    showSkyBox: true, //是否显示天空盒
    showSkyAtmosphere: true, //是否显示地球大气层外光圈
    fog: true, //是否启用雾化效果
    fxaa: true, //是否启用抗锯齿

    //以下是Cesium.Globe对象相关参数 globe 椭圆体
    globe: {
      depthTestAgainstTerrain: true, //是否启用深度监测
      baseColor: '#546a53', //地球默认背景色
      showGroundAtmosphere: true, //是否在地球上绘制的地面大气
      enableLighting: true //是否显示昼夜区域
    },
    //以下是Cesium.ScreenSpaceCameraController对象相关参数
    cameraController: {
      zoomFactor: 3.0, //鼠标滚轮放大的步长参数
      enableRotate: true, //2D和3D视图下，是否允许用户旋转相机
      enableTranslate: true, //2D和哥伦布视图下，是否允许用户平移地图
      enableTilt: true, // 3D和哥伦布视图下，是否允许用户倾斜相机
      enableZoom: true, // 是否允许 用户放大和缩小视图
      enableCollisionDetection: true, //是否允许 地形相机的碰撞检测
      maximumZoomDistance: 100000, //地球缩小的最大值（以米为单位）
      minimumZoomDistance: 1 //地球放大的最小值（以米为单位）
    },

  },
  // 控件
  control: {
    //以下是Cesium.Viewer所支持的控件相关的options
    homeButton: true, //视角复位按钮
    baseLayerPicker: true, //basemaps底图切换按钮
    sceneModePicker: true, //二三维切换按钮
    vrButton: true, //vr模式按钮
    fullscreenButton: true, //全屏按钮 
    navigationHelpButton: true, //帮助按钮
    animation: true, //动画部件按钮（左下角），控制视图动画的播放速度
    timeline: true, //时间线（下侧）,指示当前时间，并允许用户跳到特定的时间
    infoBox: true, //信息框
    geocoder: true, //POI查询按钮
    geocoderConfig: {
      key: ['ae29a37307840c7ae4a785ac905927e0']
    }, //POI查询按钮参数配置
    selectionIndicator: true, //选择框

    //以下是mars3d.control定义的控件
    defaultContextMenu: true,
    mouseDownView: true,
    zoom: {
      insertIndex: 1
    },
    compass: {
      bottom: 'toolbar',
      right: '10px'
    },
    distanceLegend: {
      left: '100px',
      bottom: '2px'
    },


    locationBar: {
      fps: true,
      crs: 'CGCS2000_GK_Zone_3',
      crsDecimal: 0,
      template: '<div>经度:{lng}</div> <div>纬度:{lat}</div> <div>横{crsx}  纵{crsy}</div> <div>海拔：{alt}米</div> <div>层级：{level}</div><div>方向：{heading}°</div> <div>俯仰角：{pitch}°</div><div>视高：{cameraHeight}米</div>'
    }
  },
  // 地形参数：地形是三维场景中的重要三维效果
  terrain: {
    //xyz：标准xyz服务(未配置时的默认值)；
    //arcgis：ArcGIS地形服务
    //ion：cesium官方ion在线服务
    //gee：谷歌地球企业版服务
    //vr：vr地形服务
    //none ：无地形，标准椭球体
    //type:'xyz',
    url: 'http://data.mars3d.cn/terrain',
    show: true //是否开启地形
  },
  // 栅格瓦片底图:地形是三维的"骨骼"，栅格底图就是我们浏览三维能感知的"皮肤"
  // 栅格底图所支持的图层类型，只能是瓦片图层，均是继承自 BaseTileLayer类 (opens new window)的图层类型。
  basemaps: [{
    name: '影像地图',
    icon: 'img/basemaps/google_vec.png',//图层缩略图，用于图层切换控件的显示
    type: 'xyz',//图层类型 标准金字塔地图
    url: 'https://mapdata.shciip.com/image/tiles/{z}/{x}/{y}',
    subdomains: 'abc',
    show: true
  }
],
  // 图层:可以叠加的图层
  layers:[
    {
      "type": "tdt", //必须的参数
      "name": "天地图注记",
      "layer": "img_z",
      "key": ["天地图token值"],
      "show": true
    },
    {
      "id":1987,
      "type": "3dtiles",
      "name": "县城社区",
      "url": "http://data.mars3d.cn/3dtiles/qx-shequ/tileset.json",
      "show": false
    },
  ]
}
// 更新scene参数
export const setSceneOptions = (options = mapOptions.scene) => {
  map.setSceneOptions({
    ...options,
    cameraController: {
      maximumZoomDistance: 500000000
    }
  })
}


// 限定地图范围
export function limitThingCamera() {
  const limitThingCameraHistory = new mars3d.thing.CameraHistory({
    limit: {
      // 限定视角范围
      position: Cesium.Cartesian3.fromDegrees(110.169988, 38.695172, 3000), // 中心点坐标
      radius: 5000.0, // 半径（单位：米）
      debugExtent: false // 是否显示限定范围的边界
    },
    maxCacheCount: 999 // 保留的历史记录最多个数
  })
  map.limitThingCameraHistory = limitThingCameraHistory
  limitThingCameraHistory && map.addThing(limitThingCameraHistory)
}

// 放大地图
export function mapZoomIn() {
  map.zoomIn()
}

// 缩小地图
export function mapZoomOut() {
  map.zoomOut()
}

// 清除图层
export const mapGraphicLayerClear = (hasDestroy) => {
  map.graphicLayer.clear(hasDestroy)
}

// 添加图层--矢量数据图层 GraphicLayer (opens new window)，业务数据的叠加
export const mapAddGraphicLayer = () => {
  map.addLayer(map.graphicLayer)
}
//三维模型图层 TilesetLayer (opens new window)，呈现更细节的三维--- 设置 TilesetLayer图层
export const setTilesetLayer = (tilesTypeMapOptions) => {
  const graphicTilesetLayer = new mars3d.layer.TilesetLayer(tilesTypeMapOptions)
  map.tilesetLayer = graphicTilesetLayer
  graphicTilesetLayer && map.addLayer(graphicTilesetLayer)
}

//  倾斜摄影-TilesetLayer 类型配置
export const tilesTypeMapOptions = {
  type: '3dtiles',
  name: '化工-倾斜摄影',
  // url: 'https://uat.shciip.com/map-qx/tileset.json',
  url: 'http://zhaj.tyci.com.cn:9009/ty-3d-3cm/tileset.json',
  position: {
    lng: 110.165991,
    lat: 38.7005,
    alt: 0
  },
  rotation: {
    z: 0
  },
  scale: 1,
  center: {
    lat: 38.70263,
    lng: 110.167847,
    alt: 0,
    heading: 342,
    pitch: -9
  },
  maximumScreenSpaceError: 32,
  maximumMemoryUsage: 1024,
  dynamicScreenSpaceError: true,
  skipLevelOfDetail: true,
  cullRequestsWhileMovingMultiplier: 10,
  progressiveResolutionHeightFraction: 0.5
}
// 添加标记
export const addSignGraphic = (data) => {
  const {
    pointName,
    ticketTypeName,
    center
  } = data
  const graphic = new mars3d.graphic.BillboardEntity({
    name: pointName || ticketTypeName || 'pointName',
    position: center,
    style: {
      width: 46,
      height: 53,
      image: computeIcon(data),
      horizontalOrigin: Cesium.HorizontalOrigin.CENTER, // 相对于对象的原点的水平位置(原点位于对象的水平中心)
      verticalOrigin: Cesium.VerticalOrigin.BOTTOM // 相对于对象的原点的垂直位置(原点位于对象的底部)
    },
    options: {
      ...data
    },
    attr: {
      remark: pointName
    }
  })
  map.graphicLayer.addGraphic(graphic)
}

// 绘制圆
export const circleStyle = {
  color: '#ffff00',
  opacity: 0.6,
  // clampToGround: true,
  outline: true,
  outlineColor: '#ffffff'
}
// 添加圆
export const addCircleGraphic = (position, radius, defineStyle = {}, data) => {
  const graphic = new mars3d.graphic.CircleEntity({
    position: position,
    style: {
      ...circleStyle,
      radius: radius,
      ...defineStyle
    },
    options: {
      ...data
    }
  })
  map.graphicLayer.addGraphic(graphic)
}

// 绘制闭面--多边形
export const polygonStyle = {
  color: '#29cf34',
  opacity: 0.5,
  outline: true,
  outlineWidth: 1,
  outlineColor: 'red'
}

// 添加多边形
export const addPolygonGraphic = (positions, defineStyle = {}, data) => {
  const graphic = new mars3d.graphic.PolygonEntity({
    positions: [
      ...positions
    ],
    style: {
      ...polygonStyle,
      ...defineStyle
    },
    options: {
      ...data
    }
  })
  map.graphicLayer.addGraphic(graphic)
}

// 在图层绑定Popup弹窗
export function bindLayerPopup() {
  const graphic = map.graphicLayer.bindPopup(function (event) {
    const config = event.graphic.options.options
    return mars3d.Util.template(bindLayerPopupTemplate(config))
  })
  // 添加模板及绑定Dom 事件
  graphic.on(mars3d.EventType.popupOpen, function (event) {
    mapPopupDomEevent(event)
  })
}

// 自定义图层控件
export function mapAddControl() {
  // 添加-切换图层视角按钮
}

// 在图层级处理一些事物
export function bindLayerEvent() {
  // 在layer上绑定监听事件
  map.graphicLayer.on(mars3d.EventType.click, function (event) {
    console.log("监听layer，单击了矢量对象", event)
  })
  // 监听滚轮事件
  map.on(mars3d.EventType.wheel, function (event) {
    console.log(" 监听滚轮事件", event)
    eventTarget.fire('map-wheel', {
      sourceTarget: event.sourceTarget
    })
  })

  // 创建完成 标绘事件， 用于属性弹窗的交互
  map.graphicLayer.on(mars3d.EventType.drawCreated, function (e) {
    console.log("drawCreated", e)
    eventTarget.fire('graphicEditor-start', {
      edittype: e.edittype,
      graphic: e.graphic
    })
  })
  // 多个事件监听
  map.graphicLayer.on(
    [mars3d.EventType.editStart, mars3d.EventType.editMovePoint, mars3d.EventType.editStyle, mars3d.EventType.editRemovePoint],
    function (e) {
      console.log("editStart，editMovePoint，editStyle，editRemovePoint", e)
      eventTarget.fire('graphicEditor-update', {
        edittype: e.edittype,
        graphic: e.graphic
      })
    }
  )

  map.graphicLayer.on([mars3d.EventType.editStop, mars3d.EventType.removeGraphic], function (e) {
    console.log("editStop", 'removeGraphic', e)
    eventTarget.fire('graphicEditor-stop', {
      graphic: e.graphic,
      type: e.type, // editStop && removeGraphic
      edittype: e.edittype
    })
  })
}

// 三维场景初始化
export const initMapInstance = (id) => {
  // 创建地图实例
  if (map) return map
  map = new mars3d.Map(id, mapOptions)
  // map && bindLayerEvent() // 对图层绑定相关事件
  map && bindLayerPopup() // 绑定弹窗
  // map && mapAddControl() // 绑定弹窗
  // map && mapSetCameraView()
  
  //用工厂方法，指定type来创建图层对象
  var layer = mars3d.LayerUtil.create({
    type: 'xyz',
    url: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.jpg',
    subdomains: 'abc', 
  }) 
  map.addLayer(layer)

  //直接创建具体类型的图层对象
  var  tileLayer = new mars3d.layer.XyzLayer({
    url: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.jpg',
    subdomains: 'abc', 
  })
  map.addLayer(tileLayer)
  return map
}